#include "mainwindow.h"
#include "ui_mainwindow.h"
#include "Agent.h"

static const char blankString[] = QT_TRANSLATE_NOOP("SettingsDialog", "N/A");

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);

    connect(ui->applyButton, &QPushButton::clicked,
            [this](){
        m_currentSettings.name = ui->serialPortInfoListBox->currentText();

        if (ui->baudRateBox->currentIndex() == 4) {
            m_currentSettings.baudRate = ui->baudRateBox->currentText().toInt();
        } else {
            m_currentSettings.baudRate = static_cast<QSerialPort::BaudRate>(
                        ui->baudRateBox->itemData(ui->baudRateBox->currentIndex()).toInt());
        }
        m_currentSettings.stringBaudRate = QString::number(m_currentSettings.baudRate);

        m_currentSettings.dataBits = static_cast<QSerialPort::DataBits>(
                    ui->dataBitsBox->itemData(ui->dataBitsBox->currentIndex()).toInt());
        m_currentSettings.stringDataBits = ui->dataBitsBox->currentText();

        m_currentSettings.parity = static_cast<QSerialPort::Parity>(
                    ui->parityBox->itemData(ui->parityBox->currentIndex()).toInt());
        m_currentSettings.stringParity = ui->parityBox->currentText();

        m_currentSettings.stopBits = static_cast<QSerialPort::StopBits>(
                ui->stopBitsBox->itemData(ui->stopBitsBox->currentIndex()).toInt());
        m_currentSettings.stringStopBits = ui->stopBitsBox->currentText();

        m_currentSettings.flowControl = static_cast<QSerialPort::FlowControl>(
                ui->flowControlBox->itemData(ui->flowControlBox->currentIndex()).toInt());
        m_currentSettings.stringFlowControl = ui->flowControlBox->currentText();

    });
    connect(ui->serialPortInfoListBox, QOverload<int>::of(&QComboBox::currentIndexChanged),
            [this](int idx){
        if (idx == -1)
            return;

        const QStringList list = ui->serialPortInfoListBox->itemData(idx).toStringList();
        ui->descriptionLabel->setText(tr("描述: %1").arg(list.count() > 1 ? list.at(1) : tr(blankString)));
        ui->manufacturerLabel->setText(tr("制造商: %1").arg(list.count() > 2 ? list.at(2) : tr(blankString)));
        ui->serialNumberLabel->setText(tr("串口号: %1").arg(list.count() > 3 ? list.at(3) : tr(blankString)));
        ui->locationLabel->setText(tr("位置: %1").arg(list.count() > 4 ? list.at(4) : tr(blankString)));
        ui->vidLabel->setText(tr("厂商ID: %1").arg(list.count() > 5 ? list.at(5) : tr(blankString)));
        ui->pidLabel->setText(tr("产品ID: %1").arg(list.count() > 6 ? list.at(6) : tr(blankString)));

    });
    connect(ui->baudRateBox, QOverload<int>::of(&QComboBox::currentIndexChanged),
            [this](int idx){
        const bool isCustomBaudRate = !ui->baudRateBox->itemData(idx).isValid();
        ui->baudRateBox->setEditable(isCustomBaudRate);
        if (isCustomBaudRate) {
            ui->baudRateBox->clearEditText();
            QLineEdit *edit = ui->baudRateBox->lineEdit();
            edit->setValidator(m_intValidator);
        }
    });
    connect(ui->serialPortInfoListBox, QOverload<int>::of(&QComboBox::currentIndexChanged),
            [this](int idx){
        const bool isCustomPath = !ui->serialPortInfoListBox->itemData(idx).isValid();
        ui->serialPortInfoListBox->setEditable(isCustomPath);
        if (isCustomPath)
            ui->serialPortInfoListBox->clearEditText();
    });
    connect(ui->toolButton_refreshPorts, &QToolButton::clicked,
            [this]() {
                qDebug() << "刷新串口列表";
                auto idx_back = ui->serialPortInfoListBox->currentIndex();
                fillPortsInfo();
                ui->serialPortInfoListBox->setCurrentIndex(std::min(idx_back, ui->serialPortInfoListBox->count() - 1));
            });
//    ui->serialPortInfoListBox->installEventFilter(this);//注册事件过滤

    setDeviceStatusSlot(false);
    connect(ui->pushButton_link, &QPushButton::clicked, [this](bool checked) {
        qDebug() << "尝试发出" << (checked ? "连接" : "关闭") << "信号";
        updateSettings();
        emit openDeviceSignal(checked);
    });

    fillPortsParameters();
    fillPortsInfo();

    _restoreState();
    updateSettings();

    m_serial = new QSerialPort(this);

    //实现输入栏自动补全和历史记录
    auto *completer = new QCompleter(this); //提供自动补全的对象可用于lineEdit和combobox
    auto *listModel = new QStringListModel(m_valueList, this);//填充模型
    completer->setModel(listModel);//填充数据来源模型
    completer->setCaseSensitivity(Qt::CaseSensitive);
    ui->lineEdit->setCompleter(completer);//使lineEdit提供自动完成
    //实现输入栏自动补全和历史记录end

    connect(m_serial, &QSerialPort::errorOccurred, [this](QSerialPort::SerialPortError error) {
        auto obj = Agent::Agent::instance().find("action_com", "QAction");
        auto action = std::dynamic_pointer_cast<Agent::Agent::Ptr<QAction> >(obj);
        switch (error) {
            case QSerialPort::NoError:
                break;
            case QSerialPort::ResourceError:
    //            QMessageBox::critical(this, tr("Critical Error"), m_serial->errorString());
                qCritical() << m_serial->errorString();
                emit action->get()->triggered(true);
                openSerialPortSlot(false);
                break;
            default:
                QMessageBox::warning(this, tr("warning"), m_serial->errorString());
                openSerialPortSlot(false);
                break;
        }
    });
    connect(m_serial, &QSerialPort::readyRead, [this](){
        QByteArray data = m_serial->readAll();
        ui->textEdit->putData(data);});
    connect(ui->textEdit, &Console::getData, this, &MainWindow::writeData);
    auto lineEditReturnPressedSlot = [this, listModel]() {
        auto str = ui->lineEdit->text() + "\r\n";
        writeData(str.toUtf8());
        {
            //保存历史记录
            QString text = ui->lineEdit->text();//获取lineEdit的数据
            if (QString::compare(text, QString("")) != 0) {//判断是不是为空
                historyAppend(text);
                listModel->setStringList(m_valueList);
            }
        }
        m_valueIter = ~0;
    };
    connect(ui->toolButton_send, &QToolButton::clicked, lineEditReturnPressedSlot);
    connect(ui->lineEdit, &QLineEdit::returnPressed, lineEditReturnPressedSlot);
    connect(ui->lineEdit, &XPLineEdit::ctrlUpPressed, [this]() {
        if (m_valueIter == ~0)
            m_valueIter = m_valueList.size() - 1;
        else
            m_valueIter = m_valueIter == 0 ? 0 : (m_valueIter - 1);
        ui->lineEdit->setText(m_valueList[m_valueIter]);
    });
    connect(ui->lineEdit, &XPLineEdit::ctrlDownPressed, [this]() {
        m_valueIter = std::min(m_valueIter + 1, m_valueList.size() - 1);
        ui->lineEdit->setText(m_valueList[m_valueIter]);
    });
    connect(this,SIGNAL(openDeviceSignal(bool)),this,SLOT(openSerialPortSlot(bool)));
    connect(this,SIGNAL(deviceStatusUpdateSignal(bool)),this,SLOT(setDeviceStatusSlot(bool)));

    _restoreState();
    ui->lineEdit->setClearButtonEnabled(true);
    listModel->setStringList(m_valueList);

    ringBuffer =new RingBuffer(256);
    mPlot=ui->plot1;
    mPlot->yAxis->setTickLabels(false);
    connect(mPlot->yAxis2, SIGNAL(rangeChanged(QCPRange)), mPlot->yAxis, SLOT(setRange(QCPRange)));
    mPlot->yAxis2->setVisible(true);
    mPlot->axisRect()->addAxis(QCPAxis::atRight);
    mPlot->axisRect()->axis(QCPAxis::atRight, 0)->setPadding(30);
    mPlot->axisRect()->axis(QCPAxis::atRight, 1)->setPadding(30);

    //添加两条曲线
    //mGraph1用于显示串口缓存队列的数据
    mGraph1 = mPlot->addGraph(mPlot->xAxis, mPlot->axisRect()->axis(QCPAxis::atRight, 0));
    //mGraph2显示模拟的正弦信号
    mGraph2 = mPlot->addGraph(mPlot->xAxis, mPlot->axisRect()->axis(QCPAxis::atRight, 1));
    mGraph1->setPen(QPen(QColor(250, 120, 0)));
    mGraph2->setPen(QPen(QColor(0, 180, 60)));

    mPlot->xAxis->setRange(-0.5,1.2);
    //添加坐标轴上的显示标签
    mTag1 = new AxisTag(mGraph1->valueAxis());
    mTag1->setPen(mGraph1->pen());
    mTag2 = new AxisTag(mGraph2->valueAxis());
    mTag2->setPen(mGraph2->pen());

    //定时器刷新显示，相当于主线程用于显示数据
    connect(&mDataTimer, SIGNAL(timeout()), this, SLOT(timerSlot()));
    mDataTimer.start(60);

    //定时接收串口数据，相当于另一个线程读取串口数据
    connect(&mSerialDataTimer, SIGNAL(timeout()), this, SLOT(timerSerialSlot()));
//    mSerialDataTimer.start(10);

    QStringList strList;
    strList<<"all"<<"pid"<<"eigen_dcrt"<<"number";
    ui->comboBox->addItems(strList);
    ui->comboBox_par_set->addItems(strList);
    strList.clear();
    strList<<"do_nothing"<<"hinf_spdfb"<<"hinf_allfb"<<"hinf_allfb_onlyspd"
          <<"adda_test"<<"adda_test_2"<<"pos_pid"
          <<"pos_pid_individ"<<"pos_hinf1"<<"pos_hinf2"<<"identify_x"<<"identify_y"<<"identify_z"
         <<"spdfb1"<<"spdfb2p0"<<"spdfb2p1"<<"spdfb2p2"<<"spdfb2p3"<<"fusion_pid1"<<"zlzh_s1";
    ui->comboBox_algoswitch->addItems(strList);
    connect(ui->actiondebug,&QAction::triggered,[=](){
        m_debugView = new DebugView(this);
        m_debugView->setFixedSize(400,600);
        m_debugView->setWindowTitle("日志");
        m_debugView->show();
//        QMainWindow *widget = new QMainWindow(this);
//        widget->setFixedSize(400,200);
//        widget->show();
//        widget->setAttribute(Qt::WA_DeleteOnClose);
        /*QDialog *dlg = new QDialog(this);
        dlg->setFixedSize(400,200);
        dlg->show();
        dlg->setAttribute(Qt::WA_DeleteOnClose);*/
    });
}

MainWindow::~MainWindow()
{
    delete ui;
}

void MainWindow::fillPortsParameters() {
    ui->baudRateBox->addItem(QStringLiteral("9600"), QSerialPort::Baud9600);
    ui->baudRateBox->addItem(QStringLiteral("19200"), QSerialPort::Baud19200);
    ui->baudRateBox->addItem(QStringLiteral("38400"), QSerialPort::Baud38400);
    ui->baudRateBox->addItem(QStringLiteral("115200"), QSerialPort::Baud115200);
    ui->baudRateBox->addItem(QStringLiteral("1152000"), 1152000);
    ui->baudRateBox->addItem(QStringLiteral("2000000"), 2000000);
    ui->baudRateBox->addItem(tr("Custom"));

    ui->dataBitsBox->addItem(QStringLiteral("8"), QSerialPort::Data8);
    ui->dataBitsBox->addItem(QStringLiteral("7"), QSerialPort::Data7);
    ui->dataBitsBox->addItem(QStringLiteral("6"), QSerialPort::Data6);
    ui->dataBitsBox->addItem(QStringLiteral("5"), QSerialPort::Data5);

    ui->parityBox->addItem(tr("None"), QSerialPort::NoParity);
    ui->parityBox->addItem(tr("Even"), QSerialPort::EvenParity);
    ui->parityBox->addItem(tr("Odd"), QSerialPort::OddParity);
    ui->parityBox->addItem(tr("Mark"), QSerialPort::MarkParity);
    ui->parityBox->addItem(tr("Space"), QSerialPort::SpaceParity);

    ui->stopBitsBox->addItem(QStringLiteral("1"), QSerialPort::OneStop);
#ifdef Q_OS_WIN
    ui->stopBitsBox->addItem(tr("1.5"), QSerialPort::OneAndHalfStop);
#endif
    ui->stopBitsBox->addItem(QStringLiteral("2"), QSerialPort::TwoStop);

    ui->flowControlBox->addItem(tr("None"), QSerialPort::NoFlowControl);
    ui->flowControlBox->addItem(tr("RTS/CTS"), QSerialPort::HardwareControl);
    ui->flowControlBox->addItem(tr("XON/XOFF"), QSerialPort::SoftwareControl);
}


void MainWindow::fillPortsInfo()
{
    ui->serialPortInfoListBox->clear();
    QString description;
    QString manufacturer;
    QString serialNumber;
    const auto infos = QSerialPortInfo::availablePorts();
    for (const QSerialPortInfo &info : infos) {
        QStringList list;
        description = info.description();
        manufacturer = info.manufacturer();
        serialNumber = info.serialNumber();
        list << info.portName()
             << (!description.isEmpty() ? description : blankString)
             << (!manufacturer.isEmpty() ? manufacturer : blankString)
             << (!serialNumber.isEmpty() ? serialNumber : blankString)
             << info.systemLocation()
             << (info.vendorIdentifier() ? QString::number(info.vendorIdentifier(), 16) : blankString)
             << (info.productIdentifier() ? QString::number(info.productIdentifier(), 16) : blankString);

        ui->serialPortInfoListBox->addItem(list.first(), list);
    }

    ui->serialPortInfoListBox->addItem(tr("Custom"));
}

void MainWindow::updateSettings()
{
    m_currentSettings.name = ui->serialPortInfoListBox->currentText();

    if (ui->baudRateBox->currentIndex() == 4) {
        m_currentSettings.baudRate = ui->baudRateBox->currentText().toInt();
    } else {
        m_currentSettings.baudRate = static_cast<QSerialPort::BaudRate>(
                    ui->baudRateBox->itemData(ui->baudRateBox->currentIndex()).toInt());
    }
    m_currentSettings.stringBaudRate = QString::number(m_currentSettings.baudRate);

    m_currentSettings.dataBits = static_cast<QSerialPort::DataBits>(
                ui->dataBitsBox->itemData(ui->dataBitsBox->currentIndex()).toInt());
    m_currentSettings.stringDataBits = ui->dataBitsBox->currentText();

    m_currentSettings.parity = static_cast<QSerialPort::Parity>(
                ui->parityBox->itemData(ui->parityBox->currentIndex()).toInt());
    m_currentSettings.stringParity = ui->parityBox->currentText();

    m_currentSettings.stopBits = static_cast<QSerialPort::StopBits>(
            ui->stopBitsBox->itemData(ui->stopBitsBox->currentIndex()).toInt());
    m_currentSettings.stringStopBits = ui->stopBitsBox->currentText();

    m_currentSettings.flowControl = static_cast<QSerialPort::FlowControl>(
            ui->flowControlBox->itemData(ui->flowControlBox->currentIndex()).toInt());
    m_currentSettings.stringFlowControl = ui->flowControlBox->currentText();

}
void MainWindow::_saveState() {
    QSettings Settings(
            QDir(QStandardPaths::writableLocation(QStandardPaths::AppDataLocation))
                    .absoluteFilePath("Settings.ini"), QSettings::IniFormat);
    Settings.setValue("SettingsDialog/Geometry", this->saveGeometry());

    //对话中的其他设置需要保存
    Settings.setValue("SettingsDialog/serialPortInfoListBox", ui->serialPortInfoListBox->currentText());
    Settings.setValue("SettingsDialog/baudRateBox", ui->baudRateBox->currentText());
    Settings.setValue("SettingsDialog/baudRateBoxIndex", ui->baudRateBox->currentIndex());
    Settings.setValue("SettingsDialog/dataBitsBox", ui->dataBitsBox->currentIndex());
    Settings.setValue("SettingsDialog/parityBox", ui->parityBox->currentIndex());
    Settings.setValue("SettingsDialog/stopBitsBox", ui->stopBitsBox->currentIndex());
    Settings.setValue("SettingsDialog/flowControlBox", ui->flowControlBox->currentIndex());
}
void MainWindow::_restoreState() {
    QSettings Settings(
            QDir(QStandardPaths::writableLocation(QStandardPaths::AppDataLocation))
                    .absoluteFilePath("Settings.ini"), QSettings::IniFormat);
    this->restoreGeometry(Settings.value("SettingsDialog/Geometry").toByteArray());

    //对话中的其他设置需要恢复
    auto com = Settings.value("SettingsDialog/serialPortInfoListBox").toString();
    if (ui->serialPortInfoListBox->findText(com) >= 0)
        ui->serialPortInfoListBox->setCurrentIndex(ui->serialPortInfoListBox->findText(com));
    ui->baudRateBox->setCurrentIndex(Settings.value("SettingsDialog/baudRateBoxIndex").toInt());
    if (!ui->baudRateBox->currentData().isValid())
        ui->baudRateBox->currentData().setValue<int>(
                Settings.value("SettingsDialog/baudRateBox").toString().toInt());

    ui->dataBitsBox->setCurrentIndex(Settings.value("SettingsDialog/dataBitsBox").toInt());
    ui->parityBox->setCurrentIndex(Settings.value("SettingsDialog/parityBox").toInt());
    ui->stopBitsBox->setCurrentIndex(Settings.value("SettingsDialog/stopBitsBox").toInt());
    ui->flowControlBox->setCurrentIndex(Settings.value("SettingsDialog/flowControlBox").toInt());
}

void MainWindow::setDeviceStatusSlot(bool opened) {
    if (opened) {
        ui->pushButton_link->setChecked(opened);
        ui->pushButton_link->setText("关闭");
        ui->pushButton_link->setToolTip("已连接，点击关闭");
    } else {
        ui->pushButton_link->setChecked(opened);
        ui->pushButton_link->setText("连接");
        ui->pushButton_link->setToolTip("已关闭，点击连接");
    }
}

MainWindow::Settings MainWindow::settings() const
{
    return m_currentSettings;
}

void MainWindow::openSerialPortSlot(bool open) {
    if (open) {
//        auto obj = Agent::Agent::instance().find("m_settings", "SettingsDialog");
//        auto settings = std::dynamic_pointer_cast<Agent::Agent::Ptr<MainWindow> >(obj)->get();
//        const Settings p = settings->settings();
        m_serial->setPortName(ui->serialPortInfoListBox->currentText());
        m_serial->setBaudRate(ui->baudRateBox->currentText().toInt());
        m_serial->setDataBits(static_cast<QSerialPort::DataBits>(
                                  ui->dataBitsBox->itemData(ui->dataBitsBox->currentIndex()).toInt()));
        m_serial->setParity( static_cast<QSerialPort::Parity>(
                                 ui->parityBox->itemData(ui->parityBox->currentIndex()).toInt()));
        m_serial->setStopBits(static_cast<QSerialPort::StopBits>(
                                  ui->stopBitsBox->itemData(ui->stopBitsBox->currentIndex()).toInt()));
        m_serial->setFlowControl(static_cast<QSerialPort::FlowControl>(
                                     ui->flowControlBox->itemData(ui->flowControlBox->currentIndex()).toInt()));
        if (m_serial->open(QIODevice::ReadWrite)) {
            qDebug() << tr("Connected to %1 : %2, %3")
                    .arg(ui->serialPortInfoListBox->currentText()).arg(ui->baudRateBox->currentText().toInt())
                        .arg(static_cast<QSerialPort::DataBits>(
                                 ui->dataBitsBox->itemData(ui->dataBitsBox->currentIndex()).toInt()));
            emit deviceStatusUpdateSignal(true);
            readData();//刷新一次缓存，可能在打开之前已经接收了很多字节了
        } else {
            emit deviceStatusUpdateSignal(false);
            QMessageBox::critical(this, tr("Error"), m_serial->errorString());
            qDebug() << (tr("Open error"));
        }
    } else {
        if (m_serial->isOpen())
            m_serial->close();
        emit deviceStatusUpdateSignal(false);
    }
}

void MainWindow::readData() {
    QByteArray data = m_serial->readAll();
    //替换\r\n
    //    qsizetype j = data.count() - 1;
    //    while ((j = data.lastIndexOf("\r\n", j)) != -1) {
    //        data.replace(j, 2, "\n");
    //        --j;
    //    }
    ui->textEdit->putData(data);
}

void MainWindow::writeData(const QByteArray &data) {
    if (m_serial->isOpen())
        m_serial->write(data);
    else {
        QMessageBox::warning(nullptr, tr("Warning"), "串口未打开");
        qWarning() << "串口未打开";
//        auto obj = Agent::Agent::instance().find("action_com", "QAction");
//        auto action = std::dynamic_pointer_cast<Agent::Agent::Ptr<QAction> >(obj);
//        emit action->get()->triggered(true);
    }
}

void MainWindow::historyAppend(QString &text) {
    if (!text.isEmpty()) {
        m_valueList.removeOne(text);
        m_valueList.append(text);
        if (m_valueList.size() > 100) {
            //处理数量太多
            m_valueList.pop_front();
        }
    }
}

//定时时间一到刷新显示
void MainWindow::timerSlot()
{
    double data=0;//默认0吧
    if(!ringBuffer->isEmpty())
    {
        //这里简化了协议解析，直接读取第二个数据值,也没有做校验
        ringBuffer->pop();
        data=ringBuffer->pop()/200.0; //为了两个曲线范围一致，进行了缩小
        ringBuffer->pop();
    }

    mGraph1->addData(mGraph2->dataCount(),data);
    mGraph2->addData(mGraph2->dataCount(), qSin(mGraph1->dataCount()/5.0)/*+qSin(mGraph1->dataCount()/50.0/0.3843)*0.25*/);

    mPlot->xAxis->rescale();
    //mGraph1->rescaleValueAxis(false, true);
    mGraph2->rescaleValueAxis(false, true);
    mPlot->xAxis->setRange(mPlot->xAxis->range().upper, 100, Qt::AlignRight);

    double graph1Value = mGraph1->dataMainValue(mGraph1->dataCount()-1);
    double graph2Value = mGraph2->dataMainValue(mGraph2->dataCount()-1);
    mTag1->updatePosition(graph1Value);
    mTag2->updatePosition(graph2Value);
    mTag1->setText(QString::number(graph1Value, 'f', 2));
    mTag2->setText(QString::number(graph2Value, 'f', 2));

    mPlot->replot();
}

//相当于线程不停的读取串口数据放入缓存
void MainWindow::timerSerialSlot()
{
    //缓冲区有空间就往里面写数据
    if(!ringBuffer->isFull())
    {
        QByteArray buf;
        buf=m_serial->readAll();
        if(buf.count()==0) return;
        for(int i=0;i<buf.count();i++)
        {
            ringBuffer->push(buf[i]);//全部入队
            qDebug()<<buf[i];
        }

    }
    qDebug()<<"timerserialslot";
}

void MainWindow::on_pb_turn_off_clicked()   {writeData("motor_off");}
void MainWindow::on_pb_turn_on_clicked()    {writeData("motor_on");}
void MainWindow::on_pb_help_clicked()       {writeData("help");}
void MainWindow::on_pb_rst_clicked()        {writeData("rst");}
void MainWindow::on_pb_pid_fusion_pid1_2_clicked()  {writeData("algo_list");}
void MainWindow::on_pb_zero_clicked()               {writeData("sensor_zero");}
void MainWindow::on_pb_zero_941b_clicked()          {writeData("sensor_zero_941b");}
void MainWindow::on_pb_motor_zero_clicked()         {writeData("motor_zero");}
void MainWindow::on_pb_par_list_clicked()
{
    QString parstr = "par_ls " + ui->comboBox->currentText();
    QByteArray parary = parstr.toLatin1();
    writeData(parary);
    qDebug()<<parary;
}
void MainWindow::on_pb_par_set_clicked()
{
    QString parstr = "par_set " + ui->comboBox_par_set->currentText() +" "+ ui->lineEdit_5->text() +" "+ ui->lineEdit_6->text();
    QByteArray parary = parstr.toLatin1();
    writeData(parary);
    qDebug()<<parary;
}
void MainWindow::on_pb_par_save_clicked()   {writeData("par_save");}
void MainWindow::on_pb_par_load_clicked()   {writeData("par_load");}
void MainWindow::on_pb_time_clicked()   {writeData("time");}
void MainWindow::on_pb_motor_output_clicked()
{
    QString parstr = "motor_output " + ui->lineEdit_7->text() +" "+ ui->lineEdit_8->text();
    QByteArray parary = parstr.toLatin1();
    writeData(parary);
    qDebug()<<parary;
}
void MainWindow::on_pb_motor_xyz_output_clicked()
{
    QString parstr = "motor_xyz_output " + ui->lineEdit_9->text() +" "+ ui->lineEdit_10->text();
    QByteArray parary = parstr.toLatin1();
    writeData(parary);
    qDebug()<<parary;
}
void MainWindow::on_pb_dac_output_2_clicked()
{
    QString parstr = "dac " + ui->lineEdit_11->text() +" "+ ui->lineEdit_12->text();
    QByteArray parary = parstr.toLatin1();
    writeData(parary);
    qDebug()<<parary;
}
void MainWindow::on_pb_dac_output_3_clicked()
{
    QString parstr = "0 " + ui->lineEdit_14->text();
    QByteArray parary = parstr.toLatin1();
    writeData(parary);
    qDebug()<<parary;
}
void MainWindow::on_pb_pid_list_clicked()   {writeData("pid_list");}
void MainWindow::on_pb_pid_pos_xy_clicked()
{
    QString parstr = "pid_set pid_pos_xy " + ui->lineEdit_xyp->text() +" "+ ui->lineEdit_xyi->text() +" "+ ui->lineEdit_xyd->text();
    QByteArray parary = parstr.toLatin1();
    writeData(parary);
    qDebug()<<parary;
}
void MainWindow::on_pb_pid_pos_z_clicked()
{
    QString parstr = "pid_set pid_pos_z " + ui->lineEdit_zp->text() +" "+ ui->lineEdit_zi->text() +" "+ ui->lineEdit_zd->text();
    QByteArray parary = parstr.toLatin1();
    writeData(parary);
    qDebug()<<parary;
}
void MainWindow::on_pb_pid_pos_individ_clicked()
{
    QString parstr = "pid_set pid_pos_individ " + ui->lineEdit_inp->text() +" "+ ui->lineEdit_ini->text() +" "+ ui->lineEdit_ind->text();
    QByteArray parary = parstr.toLatin1();
    writeData(parary);
    qDebug()<<parary;
}
void MainWindow::on_pb_pid_spdfb1_x_clicked()
{
    QString parstr = "pid_set spdfb1_x " + ui->lineEdit_spdfbp->text() +" "+ ui->lineEdit_spdfbi->text() +" "+ ui->lineEdit_spdfbd->text();
    QByteArray parary = parstr.toLatin1();
    writeData(parary);
    qDebug()<<parary;
}
void MainWindow::on_pb_pid_spdfb1_y_clicked()
{
    QString parstr = "pid_set spdfb1_y " + ui->lineEdit_spdfbp_2->text() +" "+ ui->lineEdit_spdfbi_2->text() +" "+ ui->lineEdit_spdfbd_2->text();
    QByteArray parary = parstr.toLatin1();
    writeData(parary);
    qDebug()<<parary;
}
void MainWindow::on_pb_pid_spdfb1_z_clicked()
{
    QString parstr = "pid_set spdfb1_z " + ui->lineEdit_spdfbp_3->text() +" "+ ui->lineEdit_spdfbi_3->text() +" "+ ui->lineEdit_spdfbd_3->text();
    QByteArray parary = parstr.toLatin1();
    writeData(parary);
    qDebug()<<parary;
}
void MainWindow::on_pb_pid_fusion_pid1_clicked()
{
    QString parstr = "pid_set fusion_pid1 " + ui->lineEdit_fushp->text() +" "+ ui->lineEdit_fushi->text() +" "+ ui->lineEdit_fushd->text();
    QByteArray parary = parstr.toLatin1();
    writeData(parary);
    qDebug()<<parary;
}
void MainWindow::on_pb_pid_fusion_pid1_3_clicked()
{
    QString parstr = "algo_switch " + ui->comboBox_algoswitch->currentText();
    QByteArray parary = parstr.toLatin1();
    writeData(parary);
    qDebug()<<parary;
}
void MainWindow::on_pb_pid_fusion_pid1_4_clicked()
{
    QString parstr = "algo_switch " + ui->lineEdit_algo_switch->text();
    QByteArray parary = parstr.toLatin1();
    writeData(parary);
    qDebug()<<parary;
}
void MainWindow::on_pb_vf_est_in_3_clicked()
{
    QString parstr = "vf_est_in " + ui->lineEdit_4->text();
    QByteArray parary = parstr.toLatin1();
    writeData(parary);
    qDebug()<<parary;
}
void MainWindow::on_pb_vf_stop_clicked()    {writeData("vf_stop");}
void MainWindow::on_pb_vf_on_x_clicked()    {writeData("vf_on_x");}
void MainWindow::on_pb_vf_result_clicked()  {writeData("vf_result");}